import time, io
import sys, os
from datetime import datetime
from PIL import ImageGrab, Image
import win32con, win32api
import configparser
import requests
import base64
import json
import openpyxl
import re

class OCRstd():

    access_token  = ''

    rmtmpimage    = True
    rmdatajson    = True
    bisdiffday    = 0

    def __init__(self):
        self.sys_time = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
        if not os.path.exists('./data'):
            os.mkdir('./data')
        if not os.path.exists('./tmp'):
            os.mkdir('./tmp')

    def redef(self):
        config = configparser.ConfigParser()
        config.read('User.ini')

        self.screen_left   = config.getint('Screen', 'Left')
        self.screen_top    = config.getint('Screen', 'Top')
        self.screen_width  = config.getint('Screen', 'Width')
        self.screen_height = config.getint('Screen', 'Height')

        self.pager_left    = config.getint('Pager', 'Left')
        self.pager_top     = config.getint('Pager', 'Top')
        self.pager_shift   = config.getint('Pager', 'Shift')

        self.menu_left     = config.getint('Menu', 'Left')
        self.menu_top      = config.getint('Menu', 'Top')

        self.close_left    = config.getint('Close', 'Left')
        self.close_top     = config.getint('Close', 'Top')

        self.table_left    = config.getint('Table', 'Left')
        self.table_top     = config.getint('Table', 'Top')
        self.table_shift   = config.getint('Table', 'Shift')

        self.minimize_left = config.getint('Minimize', 'Left')
        self.minimize_top  = config.getint('Minimize', 'Top')

        self.appcode       = config.get('Api', 'Appcode')
        self.api_key       = config.get('Api', 'api_key')
        self.secret_key    = config.get('Api', 'secret_key')


        return self

    def screen(self, left, top, width, height):
        try:
            sbox = (left, top, left + width, top + height)
            img = ImageGrab.grab(sbox)
            newfilename = './tmp/{}.jpg'.format(int(time.time() * 1000))
            img.save(newfilename)
            print('screen saved < {}'.format(newfilename))
            return newfilename
        except Exception as e:
            print('error:', e)
            return ''

    def baidocr(self, fpath):
        if self.access_token == '':
            try:
                res = requests.get('https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id={}&client_secret={}'.format(self.api_key, self.secret_key)).json()
                if 'access_token' in res:
                    self.access_token = res['access_token']
                else:
                    print('baidubce oauth token error')
            except Exception as e:
                print(str(e))
        encodestr = ''
        with open(fpath, 'rb') as f:
            data = f.read()
            encodestr = str(base64.b64encode(data),'utf-8')
        params = {'image': encodestr}
        request_url  = 'https://aip.baidubce.com/rest/2.0/ocr/v1/accurate_basic?access_token={}'.format(self.access_token)
        headers  = {'content-type': 'application/x-www-form-urlencoded'}
        content  = ''
        try:
            response = requests.post(request_url, data=params, headers=headers).json()
            if 'error_msg' in response:
                print('百度OCR接口返回错误：'.format(response['error_msg']))
            if 'words_result' in response:
                result   = response['words_result']
                for word in result:
                    content = content + word['words']
        except Exception as e:
            print('百度OCR接口请求出错：'.format(str(e)))
        return content

    def aliocr(self, fpath):
        encodestr = ''
        with open(fpath, 'rb') as f:
            data = f.read()
            encodestr = str(base64.b64encode(data),'utf-8')
        data = {
            'img': encodestr
        }
        headers = {
            'Authorization': 'APPCODE {}'.format(self.appcode),
            'Content-Type': 'application/json; charset=UTF-8'
        }
        content = ''
        try:
            res = requests.post(url='https://gjbsb.market.alicloudapi.com/ocrservice/advanced', headers=headers, json=data).json()
            if 'error_msg' in res:
                print(res['error_msg'])
            #with open('./words.txt', 'w') as f:
            #    f.write(json.dumps(res))
            #prism_wordsInfo  = res['prism_wordsInfo']
            #for prism in prism_wordsInfo:
            #    print(prism['word'])
            content = res['content']
        except Exception as e:
            print(str(e))

        if self.rmtmpimage is True:
            os.remove(fpath)
        return content

    def words(self, fpath):
        return self.baidocr(fpath)

    def click(self, left, top):
        win32api.SetCursorPos((left, top))
        win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0)
        win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0)

    def warn(self):
        for i in range(1, 15):
            sys.stdout.write('\r {}秒后开始启动，请最小化命令行窗口'.format(15-i))
            sys.stdout.flush()
            time.sleep(1)
        print('.')

    def run(self):
        self.warn()
        self.time_start = int(time.time())
        # 遍历分页列表
        for i in range(1, 30):
            # 遍历公司列表
            _table_top = self.table_top
            for j in range(1, 11):
                business = []
                # 企业名称
                fpath = self.screen(self.table_left-40, _table_top-20, 250, 40)
                title = self.words(fpath)
                print('click on > {}'.format(title))
                self.click(self.table_left, _table_top)
                _table_top += self.table_shift
                time.sleep(6)
                # 商机列表
                print('click on > {} - 商机列表'.format(title))
                self.click(self.menu_left, self.menu_top)
                time.sleep(4)
                # 商机截图
                for k in range(0, 8):
                    fpath  = self.screen(self.screen_left, self.screen_top, self.screen_width, self.screen_height)
                    #todo:合并单元分割图为一个图再识别 
                    fpath  = self.screen(self.screen_left, int(self.screen_top)+(65*k), 145, 65)
                    shangj = self.words(fpath)
                    fpath  = self.screen(int(self.screen_left)+145, int(self.screen_top)+(65*k), 105, 65)
                    bianma = self.words(fpath)
                    if bianma == '':
                        break
                    fpath  = self.screen(int(self.screen_left)+250, int(self.screen_top)+(65*k), 95, 65)
                    fuzren = self.words(fpath)
                    fpath  = self.screen(int(self.screen_left)+345, int(self.screen_top)+(65*k), 200, 65)
                    bumen  = self.words(fpath)
                    fpath  = self.screen(int(self.screen_left)+545, int(self.screen_top)+(65*k), 280, 65)
                    create = self.words(fpath)
                    fpath  = self.screen(int(self.screen_left)+725, int(self.screen_top)+(65*k), 320, 65)
                    gengj  = self.words(fpath)

                    _biss  = {
                        'title' : title,
                        'shangj': shangj,
                        'bianma': bianma,
                        'fuzren': fuzren,
                        'bumen' : bumen,
                        'create': create,
                        'gengj' : gengj
                    }
                    business.append(_biss)
                    print('business < {} - {} - {} - {} - {} - {}'.format(shangj, bianma, fuzren, bumen, create, gengj))
                    time.sleep(1)

                with open('./data/{}.json'.format(title), 'w') as f:
                    f.write(json.dumps(business))
                print('business saved < ./data/{}.json'.format(title))

                self.click(self.close_left, self.close_top)
                time.sleep(1)

            # 翻页
            if i < 4 or i > 26:
                self.pager_left += self.pager_shift
            print('click on > page-{}'.format(i))
            self.click(self.pager_left, self.pager_top)
            time.sleep(10)
        # 最小化
        self.click(self.minimize_left, self.minimize_top)

    def writeExcel(self):
        filenum = 0
        fileset = set()
        for root, dirs, files in os.walk('./data'):
            for f in files:
                if f.endswith('.json'):
                    fileset.add(os.path.join(root, f))
                    filenum += 1
        fileset = list(fileset)
        outwb = openpyxl.Workbook()
        outws = outwb.create_sheet(index=0)
        row   = 0
        tmp_shangj = ''
        tmp_bianma = ''
        for i in range(0, filenum):
            fpath = fileset[i]
            print('convert format > {}'.format(fpath))
            with open(fpath, 'r') as f:
                res = json.load(f)
                if len(res) > 0:
                    for dt in res:
                        # 只保存最近7天数据
                        if self.bisdiffday > 0:
                            if self.diff_days(self.sys_time, create_time) > self.bisdiffday:
                                continue
                        if tmp_shangj != dt['shangj'].replace(' ','') and tmp_bianma != dt['bianma'].replace(' ',''):
                        	row += 1
                        	tmp_shangj  = dt['shangj'].replace(' ','')
                        	tmp_bianma  = dt['bianma'].replace(' ','')
                        	tmp_time    = re.sub('\D', '', dt['create'][10:])
                        	create_time = '{} {}:{}:{}'.format(dt['create'][:10], tmp_time[:2], tmp_time[2:4], tmp_time[4:])

	                        outws.cell(row, 1).value = dt['title']
	                        outws.cell(row, 2).value = dt['shangj']
	                        outws.cell(row, 3).value = dt['bianma']
	                        outws.cell(row, 4).value = dt['fuzren']
	                        outws.cell(row, 5).value = dt['bumen']
	                        outws.cell(row, 6).value = create_time
	                        outws.cell(row, 7).value = dt['gengj']
            if self.rmdatajson is True:
                os.remove(fpath)

        tm2 = time.strftime('%Y-%m-%d-%H%M%S', time.localtime(time.time()))
        saveExcel = 'business-{}.xlsx'.format(tm2)
        outwb.save(saveExcel)
        print('business saved < {}'.format(saveExcel))
        self.timeused(self.time_start)

    def timeused(self, time_start):
        seconds = int(time.time()) - time_start
        m, s = divmod(seconds, 60)
        h, m = divmod(m, 60)
        print('time used %d:%02d:%02d' % (h, m, s))

    def diff_days(self, tm1, tm2):
        tm1 = datetime.strptime(tm1, '%Y-%m-%d %H:%M:%S')
        tm2 = datetime.strptime(tm2, '%Y-%m-%d %H:%M:%S')
        return (tm1 - tm2).days

    def test(self):
        fpath  = self.screen(self.screen_left, self.screen_top, self.screen_width, self.screen_height)
        words = self.words(fpath)
        print(words)


if __name__ == '__main__':
    std = OCRstd()
    std.redef().run()
    std.writeExcel()
